package tk.mybatis.springboot.common.base;

import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.springboot.common.Page;
import tk.mybatis.springboot.common.Result;
import tk.mybatis.springboot.model.BaseEntity;
import tk.mybatis.springboot.util.MyMapper;

import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

/**
 * Created by Administrator on 2017/8/10.
 */
public abstract class BaseServiceImpl<M extends MyMapper<T>, T extends BaseEntity> implements IBaseService<T> {
    @Autowired
    protected M mapper;

    /**
     * 通用获取实体对象方法，如需要使用缓存则需要重写此方法，并加上@Cacheable(key = "#id")注解
     *
     * @param: id
     * @return: T
     * @throws: Exception
     */
    public T getById(Object id) throws Exception {
        return mapper.selectByPrimaryKey(id);
    }

    public List<T> getAll() throws Exception {
        return mapper.selectAll();
    }

    public List<T> getByExample(Example example) throws Exception {
        return mapper.selectByExample(example);
    }

    public T getUniqueByExample(Example example) throws Exception {
        List<T> users = getByExample(example);
        if (users == null) {
            return null;
        }
        return users.get(0);
    }

    public void deleteById(Object id) throws Exception {
        mapper.deleteByPrimaryKey(id);
    }

    public void delByIds(String ids) throws Exception {
        mapper.deleteByIds(ids);
    }

    @CacheEvict(key = "#obj.id")
    public void updateById(T obj) throws Exception {
        mapper.updateByPrimaryKey(obj);
    }

    public void save(T obj) throws Exception {
        mapper.insert(obj);
    }

    public abstract void savAll(List<T> list) throws Exception;

    /**
     * 通用分页获取数据
     *
     * @param sqlId
     * @param page
     * @param params
     * @return Result<T>
     * @throws Exception
     */
    public Result<T> getRecordPage(String sqlId, Page page, Map<String, Object> params) throws Exception {
        Method method;
        try {
            // 根据sqlId反射获取对应方法
            method = mapper.getClass().getMethod(sqlId, Map.class);
        } catch (Exception e) {
            throw new RuntimeException(sqlId + "目标方法未定义");
        }
        try {
            com.github.pagehelper.Page<?> listPage = PageHelper.startPage(page.getCurPage(), page.getRowPerPage(), true);
            // 执行方法，查询数据
            method.invoke(mapper, params);
            page.setTotalPages(listPage.getPages());
            page.setTotalRows(new Long(listPage.getTotal()).intValue());
            return new Result(page, listPage.getResult());
        } catch (Exception e) {
            throw new RuntimeException("系统内部错误");
        }
    }
}
